package com.badger.generator.pattern;

import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.SQLException;
import java.util.List;

import com.badger.generator.constant.DataBaseDriver;
import com.badger.generator.entity.GeneratorAttr;
import com.badger.generator.enums.DataBaseFieldEnum;
import com.badger.generator.enums.DataBaseType;

/**
 * 构建生成文件所需要的表的信息以及字段信息的数据
 * @author liqi
 *
 */
public final class PostgreSqlStrategy extends AbstractDataBaseStrategy {

    /**PostgreSql 查询所有的表*/
    public static final String SELECT_TABLE = "SELECT A.tablename, obj_description(relfilenode, 'pg_class') AS comments FROM pg_tables A, pg_class B WHERE A.schemaname='%s' AND A.tablename = B.relname ORDER BY tablename";
    /**PostgreSql 查询表的字段明细*/
    public static final String SELECT_FIELD = "SELECT A .attname AS NAME, format_type (A .atttypid, A .atttypmod) AS TYPE, col_description (A .attrelid, A .attnum) AS COMMENT, ( CASE C .contype WHEN 'p' THEN 'PRI' ELSE '' END ) AS KEY, ( CASE A .attnotnull WHEN 't' THEN 'NO' ELSE 'YES' END ) AS attnotnull FROM pg_attribute A LEFT JOIN pg_constraint C ON A .attnum = C .conkey [ 1 ] AND A .attrelid = C .conrelid WHERE A .attrelid = '%s.%s' :: regclass AND A .attnum > 0 AND NOT A .attisdropped ORDER BY A.attnum";

    public static final String PATTERN = "public";

    public PostgreSqlStrategy(Connection connection, DataBaseFieldEnum fieldEnum, List<String> tables,
            List<String> includePrefix) {
        super(connection, fieldEnum, tables, includePrefix);
    }

    /**
     * @param attr
     * @return
     */
    public static AbstractDataBaseStrategy getInstance(GeneratorAttr attr) {
        try {
            Connection conn = DriverManager.getConnection(attr.getUrl(), attr.getUser(), attr.getPassword());
            Class.forName(DataBaseDriver.POSTGRE_SQL);
            return new PostgreSqlStrategy(conn, DataBaseFieldEnum.POSTGRE_SQL, attr.getTables(),
                    attr.getIncludePrefix());
        } catch (SQLException | ClassNotFoundException e) {
            throw new RuntimeException(e);
        }
    }

    @Override
    String getTableSql() {
        return String.format(SELECT_TABLE, PATTERN);
    }

    @Override
    String getFieldSql(String tableName) {
        return String.format(SELECT_FIELD, PATTERN, tableName);
    }

    @Override
    DataBaseType typeConvert(String fieldType) {
        return ConvertSingleFactory.getInstance().build(DataBaseDriver.POSTGRE_SQL).processTypeConvert(fieldType);
    }

}
